package com.ad2campaign.engine.core.service;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.ad2campaign.engine.db.model.NotificationMessage;
import com.ad2campaign.engine.utils.KeystoreHolder;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Message.Builder;
import com.google.android.gcm.server.MulticastResult;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;

public class AndroidPushNotificationServiceImpl implements PushNotificationService{
	private static final Logger LOGGER = Logger.getLogger(AndroidPushNotificationServiceImpl.class);

	private int timeToLive;
	private boolean delayWhileTrue;
	private int retries;
	private String key_val;

	public List<? extends NotificationMessage> sendPushNotification(List<? extends NotificationMessage> messages,KeystoreHolder keystoreHolder){
		if(messages.size()==0){
			LOGGER.info(" Android ----- Empty list, not pushing to anyone -----");
			return messages;
		}
		
		List<String> registrationIdList = new ArrayList<String>();
		String notificationPushId = "";
		Iterator<? extends NotificationMessage> itr = messages.iterator();
		while(itr.hasNext()){
			NotificationMessage message = itr.next();
			registrationIdList.add(message.getTokenId());
			notificationPushId = message.getnId()+"";
		}
		LOGGER.info(notificationPushId+" @Pushing message to android");

		Sender sender = new Sender(keystoreHolder.getAndroidApiKey());
		Builder builder = new Message.Builder();
		builder.addData("nId",notificationPushId);
		builder.timeToLive(this.getTimeToLive());
		builder.delayWhileIdle(this.isDelayWhileTrue());

		if(this.getKey_val() != null){
			String[] keyValArr = this.getKey_val().split("###");
			for(int i=0;i<keyValArr.length;i++){
				if(keyValArr[i].contains("=")){
					String[] kv = keyValArr[i].split("=");
					try{
						builder.addData(URLDecoder.decode(kv[0],"UTF-8"),URLDecoder.decode(kv[1],"UTF-8"));
					}catch (UnsupportedEncodingException e){
						LOGGER.info(notificationPushId+" @UnsupportedEncodingException:",e);
					}
				}
			}
		}
		

		Message message = builder.build();
		MulticastResult mulresult = null;
		
		try{
			mulresult = sender.send(message, registrationIdList, this.getRetries());
		}catch (IOException e) {
			LOGGER.info(notificationPushId+" @IOException:",e);
		}
		List<Result> resultsList = mulresult.getResults();
		Iterator<Result> resultItr = resultsList.iterator();
		LOGGER.info("|||||||||||||||||||||||| resultsList.size="+resultsList.size()+
				"messages.size"+messages.size());

		Iterator<? extends NotificationMessage> messageItr = messages.iterator();
		while(resultItr.hasNext() && messageItr.hasNext()){
			Result result = resultItr.next();
			NotificationMessage msg = messageItr.next();
			if(result.getErrorCodeName()!=null){
				msg.setDelivered(0);
				msg.setResponse(result.getErrorCodeName());
			}else{
				msg.setDelivered(1);
				msg.setResponse("SUCCESS");
			}
			if(result.getCanonicalRegistrationId()!=null){
				msg.setTokenId(result.getCanonicalRegistrationId());
			}
			msg.setStatus(1);
		}
		return messages;
	}

	public int getTimeToLive() {
		return timeToLive;
	}

	public void setTimeToLive(int timeToLive) {
		this.timeToLive = timeToLive;
	}

	public boolean isDelayWhileTrue() {
		return delayWhileTrue;
	}

	public void setDelayWhileTrue(boolean delayWhileTrue) {
		this.delayWhileTrue = delayWhileTrue;
	}

	public String getKey_val() {
		return key_val;
	}

	public void setKey_val(String key_val) {
		this.key_val = key_val;
	}

	public int getRetries() {
		return retries;
	}

	public void setRetries(int retries) {
		this.retries = retries;
	}


}
